﻿using UnityEngine;
using UnityEngine.EventSystems; 
using System;

/// <summary>
/// 摇杆
/// </summary>
[RequireComponent(typeof(RectTransform))]
public class Joystick : MonoBehaviour, IPointerDownHandler, IDragHandler, IPointerUpHandler
{
    /// <summary>
    /// 摇杆纽
    /// </summary>
    public RectTransform handle;
    /// <summary>
    /// 摇杆松开后的回弹速度
    /// </summary>
    public Vector2 autoReturnSpeed = new Vector2(4.0f, 4.0f);
    public float radius = 40.0f;

    public event Action<Joystick, Vector2> OnStartJoystickMovement;
    public event Action<Joystick, Vector2> OnJoystickMovement;
    public event Action<Joystick> OnEndJoystickMovement;
    /// <summary>
    /// 是否在操作
    /// </summary>
    private bool isCtrl;
    private RectTransform rt;

    /// <summary>
    /// 方向
    /// </summary>
    public Vector2 Direction
    {
        get
        {
            if (handle.anchoredPosition.magnitude < radius)
            {
                return handle.anchoredPosition / radius;
            }
            return handle.anchoredPosition.normalized;
        }
    }

    void IPointerDownHandler.OnPointerDown(PointerEventData eventData)
    {
        isCtrl = false;
        var handleOffset = GetJoystickOffset(eventData);
        handle.anchoredPosition = handleOffset;
        if (OnStartJoystickMovement != null)
        {
            OnStartJoystickMovement(this, Direction);
        }
    }

    void IDragHandler.OnDrag(PointerEventData eventData)
    {
        var handleOffset = GetJoystickOffset(eventData);
        handle.anchoredPosition = handleOffset;
        if (OnJoystickMovement != null)
        {
            OnJoystickMovement(this, Direction);
        }
    }

    void IPointerUpHandler.OnPointerUp(PointerEventData eventData)
    {
        isCtrl = true;
        if (OnEndJoystickMovement != null)
        {
            OnEndJoystickMovement(this);
        }
    }

    private Vector2 GetJoystickOffset(PointerEventData eventData)
    {
        Vector3 globalHandle;
        if (RectTransformUtility.ScreenPointToWorldPointInRectangle(rt, eventData.position, eventData.pressEventCamera, out globalHandle))
        {
            handle.position = globalHandle;
        }
        var handleOffset = handle.anchoredPosition;
        if (handleOffset.magnitude > radius)
        {
            handleOffset = handleOffset.normalized * radius;
            handle.anchoredPosition = handleOffset;
        }
        return handleOffset;
    }

    private void Start()
    {
        isCtrl = true;
        var touchZone = GetComponent<RectTransform>();
        touchZone.pivot = Vector2.one * 0.5f;
        handle.transform.SetParent(transform);

        rt = transform.parent.GetComponent<RectTransform>();
         
    }

    private void Update()
    {
        if (isCtrl)
        {
            if (handle.anchoredPosition.magnitude > Mathf.Epsilon)
            {
                handle.anchoredPosition -= new Vector2(handle.anchoredPosition.x * autoReturnSpeed.x, handle.anchoredPosition.y * autoReturnSpeed.y) * Time.deltaTime;
            }
            else
            {
                isCtrl = false;
            }
        }
    }
}